package cc.magicjson.summary.errors.connection.closed.controller;


import cc.magicjson.summary.errors.connection.closed.entity.User;
import cc.magicjson.summary.errors.connection.closed.monitor.MethodStopWatch;
import cc.magicjson.summary.errors.connection.closed.service.UserService;
import org.apache.ibatis.session.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired(required = false)
    private Configuration mybatisConfiguration;

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/batch")
    public String batchInsert() {
        System.out.println(mybatisConfiguration);
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 30000; i++) {
            User user = new User();
            user.setName("User" + i);
            user.setEmail("user" + i + "@example.com");
            users.add(user);
        }

            long start = System.currentTimeMillis();
            new MethodStopWatch(getClass().getSimpleName()).monitor(()->userService.batchInsert(users));
            long end = System.currentTimeMillis();
            return "Batch insert completed in " + (end - start) + " ms";

    }

    @PostMapping("/single")
    public String singleInsert() throws InterruptedException {
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 30000; i++) {
            User user = new User();
            user.setName("User" + i);
            user.setEmail("user" + i + "@example.com");
            users.add(user);
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        new MethodStopWatch(getClass().getSimpleName()).monitorWithTable("user",()->{
            for (User user : users) {
                userService.insertOne(user);
            }
            return users.size();
        });

        System.err.printf("size:%s",userService.findAll().size());
        stopWatch.stop();
        return "Single insert completed in " + stopWatch.getTotalTimeMillis() + " ms";
    }

    @PostMapping("/batch/rewrite")
    public Integer batchInsertWithRewriteBatchedStatements() {
        return new MethodStopWatch(getClass().getSimpleName()).monitorWithTable("user", () -> {
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 30000; i++) {
                User user = new User();
                user.setName("User" + i);
                user.setEmail("user" + i + "@example.com");
                users.add(user);
            }
            userService.batchInsertWithRewriteBatchedStatements(users);
            return users.size();
        });
    }

    @PostMapping("/batch/named-parameter")
    public Integer batchInsertWithNamedParameter() {
        return new MethodStopWatch(getClass().getSimpleName()).monitorWithTable("user", () -> {
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 30000; i++) {
                User user = new User();
                user.setName("User" + i);
                user.setEmail("user" + i + "@example.com");
                users.add(user);
            }
            userService.batchInsertWithNamedParameter(users);
            return users.size();
        });
    }

    @PostMapping("/batch/template")
    public Integer batchInsertWithJdbcTemplate() {
        return new MethodStopWatch(getClass().getSimpleName()).monitorWithTable("user", () -> {
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 30000; i++) {
                User user = new User();
                user.setName("User" + i);
                user.setEmail("user" + i + "@example.com");
                users.add(user);
            }
            userService.batchInsertWithJdbcTemplate(users);
            return users.size();
        });
    }


    @GetMapping("/all")
    public Integer findAll() {
        return userService.findAll().size();
    }

    @DeleteMapping("/delete/all")
    public Integer deleteAll() {
        return userService.deleteAll();
    }

    @PostMapping("/single/xml")
    public String singleInsertByXml() throws InterruptedException {
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 30000; i++) {
            User user = new User();
            user.setName("User" + i);
            user.setEmail("user" + i + "@example.com");
            users.add(user);
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        new MethodStopWatch(getClass().getSimpleName()).monitorWithTable("user",()->{
            for (User user : users) {
                userService.insertByXml(user);
            }
            return users.size();
        });

        System.err.printf("size:%s",userService.findAll().size());
        stopWatch.stop();
        return "Single insert completed in " + stopWatch.getTotalTimeMillis() + " ms";
    }

    @PostMapping("/simulate-connection-closed")
    public String simulateConnectionClosed() {
        try {
            userService.simulateConnectionClosed();
            return "This should not be reached";
        } catch (Exception e) {
            return "Error: " + e.getMessage();
        }
    }
}
